<?php

/**
 * Description of ArrayFunctions
 *
 * @author a.novikov
 */
class ArrayFunctions {

	/**
	 *
	 * @param array $arr
	 * @param string $prefix
	 * @param string $suffix
	 * @return array
	 */
	public static function wrapKeys(array $arr, $prefix = '', $suffix = '') {
		$result = array();

		foreach ($arr as $key => $value) {
			$result[$prefix.$key.$suffix] = $value;
		}

		return $result;
	}

	/**
	 * Если переменная не является массивом, кладёт её в массив. !!! Меняет саму переменную !!!
	 *
	 * @param mixed $var
	 * @return array
	 */
	public static function makeArray(&$var) {
		if (!is_array($var)) {
			$var = array($var);
		}
		return $var;
	}

	public static function implode($arr, $separator = ',', $veryfyType = true) {
		if ($veryfyType) {
			self::makeArray($arr);
		}
		return implode($separator, $arr);
	}

	/**
	 *
	 * @param array[]int $arr
	 * @param string $separator
	 * @return string
	 */
	public static function implodeIntegers($arr, $separator = ',') {
		self::intArray($arr);
		return implode($separator, $arr);
	}

	/**
	 *
	 * @param array[]int $arr
	 */
	public static function intArray(&$arr) {
		self::makeArray($arr);
		foreach ($arr as &$value) {
			$value = (int)$value;
		}
		return $arr;
	}

	/**
	 *
	 * @param array $arr
	 * @return mixed
	 */
    public static function extractFirst(&$arr) {
		self::makeArray($arr);
    	$current_value = current($arr);
    	$current_key = key($arr);
    	unset($arr[$current_key]);
    	return $current_value;
    }

	/**
	 * Check if $array is not an associative array
	 *
	 * @param mixed $array
	 * @return bool
	 */
	public static function isNotAssoc($array) {
		return (is_array($array) && (!count($array) || !count(array_diff_key($array, array_values($array)) )));
	}

	/**
	 *
	 * @param array|object $source
	 * @param string $fieldName
	 * @return mixed
	 */
	public static function getField($source, $fieldName) {
		if (is_array($source)) {
			if (!array_key_exists($fieldName, $source)) {
				throw new Exception("Array does not contain key '{$fieldName}'");
			}
			return $source[$fieldName];
		}
		elseif (is_object($source)) {
			return $source->$fieldName;
		}
		else {
			throw new Exception('Source is neither array nor object');
		}
	}

	/**
	 *
	 * @param array $list
	 * @param array|string $keyFields
	 * @param string|null $valueField
	 * @param bool $multiValue
	 * @return array
	 */
	public static function normalize($list, $keyFields, $valueField = null, $multiValue = false) {
		self::makeArray($keyFields);

		$result = array();
		foreach ($list as $element) {

			$current = &$result;
			foreach ($keyFields as $keyField) {
				$key = self::getField($element, $keyField);
				Lib::set_default($current[$key], array());
				$current = &$current[$key];
			}

			if ( isset($valueField) ) {
				$element = self::getField($element, $valueField);
			}

			if ($multiValue) {
				$current[] = $element;
			}
			else {
				$current = $element;
			}
		}
		return $result;
	}
}